package cn.wlinker.driver.modbus.tcp.utils;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.log.StaticLog;
import cn.wlinker.driver.modbus.tcp.constant.Constant;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.ip.IpParameters;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * modbusTcp主站工具类
 *
 * @author gxsjx
 * @version 1.0
 * @date 2022/10/10
 * Copyright © wlinker.cn
 */
public class ModbusMasterHelper {

    private static final ModbusFactory modbusFactory = new ModbusFactory();

    private static final Map<String, ModbusMaster> masterMap = new ConcurrentHashMap<>();

    static String getKey(String ip, Integer port) {
        return CharSequenceUtil.format("{}:{}", ip, port);
    }

    /**
     * 断连master
     */
    public static synchronized boolean removeMaster(String ip, Integer port) {
        String key = getKey(ip, port);
        ModbusMaster modbusMaster = masterMap.get(key);
        if (modbusMaster != null) {
            modbusMaster.destroy();
            masterMap.remove(key);
            return true;
        }
        return false;
    }

    /**
     *  通过ip获取对应的modbus连接器
     */
    public static synchronized ModbusMaster getMaster(String ip, Integer port) {
        String key = getKey(ip, port);
        ModbusMaster modbusMaster = masterMap.get(key);
        if (modbusMaster == null) {
            initMaster(ip, port);
            modbusMaster = masterMap.get(key);
        }
        return modbusMaster;

    }

    /**
     * 设置ip和端口号对应的modbus连接器
     */
    private static void initMaster(String ip, Integer port) {
        ModbusMaster master;
        IpParameters params = new IpParameters();
        params.setHost(ip);
        params.setPort(port);
        // TCP 协议
        master = modbusFactory.createTcpMaster(params, false);
        try {
            //设置超时时间
            master.setTimeout(Constant.TIMEOUT_MS);
            //设置重连次数
            master.setRetries(Constant.RETRIES);
            //初始化
            master.init();
        } catch (ModbusInitException e) {
            e.printStackTrace();
            StaticLog.info(e.getMessage());
        }
        String key = getKey(ip, port);
        masterMap.put(key, master);
    }


}